<template>
  <div id="signature">
    <el-container>
      <el-header>文件签名工具</el-header>
      <el-main>
        <el-tabs v-model="activeTab" type="border-card">
          <el-tab-pane label="生成签名" name="sign">
            <el-upload
                class="upload-demo"
                drag
                action="#"
                :on-change="handleSignFileChange"
                :auto-upload="false"
            >
              <i class="el-icon-upload"></i>
              <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
            </el-upload>

            <el-button @click="generateSignature" type="primary">生成签名</el-button>

            <p v-if="signature">生成的签名已自动下载</p>
          </el-tab-pane>

          <el-tab-pane label="验证签名" name="verify">
            <el-upload
                class="upload-demo"
                drag
                action="#"
                :on-change="handleVerifyFileChange"
                :auto-upload="false"
            >
              <i class="el-icon-upload"></i>
              <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
            </el-upload>

            <el-upload
                class="upload-demo"
                drag
                action="#"
                :on-change="handleSignatureChange"
                :auto-upload="false"
            >
              <i class="el-icon-upload"></i>
              <div class="el-upload__text">将签名文件拖到此处，或<em>点击上传</em></div>
            </el-upload>

            <el-upload
                class="upload-demo"
                drag
                action="#"
                :on-change="handlePublicKeyFileChange"
                :auto-upload="false"
            >
              <i class="el-icon-upload"></i>
              <div class="el-upload__text">将公钥文件拖到此处，或<em>点击上传</em></div>
            </el-upload>

            <el-button @click="verifySignature" type="primary">验证签名</el-button>

            <p v-if="verificationResult">{{ verificationResult }}</p>
          </el-tab-pane>
        </el-tabs>
      </el-main>
    </el-container>
  </div>
</template>

<script>
import CryptoJS from 'crypto-js';
import { JSEncrypt } from 'jsencrypt';

const privateKey = JSON.parse(localStorage.getItem('xm-user') || '{}').privateKey;
console.log("user++:::", privateKey);

export default {
  name: 'FileSignature',
  data() {
    return {
      activeTab: 'sign',
      signFile: null,
      verifyFile: null,
      signatureFile: null,
      publicKey: '',
      signature: '',
      verificationResult: ''
    };
  },
  methods: {
    handleSignFileChange(file) {
      this.signFile = file.raw;
    },
    handleVerifyFileChange(file) {
      this.verifyFile = file.raw;
    },
    handleSignatureChange(file) {
      const reader = new FileReader();
      reader.onload = (event) => {
        this.signature = event.target.result.trim();
        console.log('Loaded Signature:', this.signature);
      };
      reader.readAsText(file.raw);
    },
    handlePublicKeyFileChange(file) {
      const reader = new FileReader();
      reader.onload = (event) => {
        this.publicKey = event.target.result.trim();
        console.log('Loaded Public Key:', this.publicKey);
      };
      reader.readAsText(file.raw);
    },
    generateSignature() {
      if (!privateKey) {
        alert('密钥获取失败，系统异常');
        return;
      }
      if (!this.signFile) {
        alert('请选择文件');
        return;
      }

      const reader = new FileReader();
      reader.onload = (event) => {
        try {
          const fileContent = event.target.result;
          console.log('File content length:', fileContent.length);

          const hash = this.calculateHash(fileContent);
          console.log('Generated Hash:', hash);

          const jsEncrypt = new JSEncrypt();
          jsEncrypt.setPrivateKey(privateKey);

          // Generate the signature
          const signature = jsEncrypt.sign(hash, CryptoJS.SHA256, "sha256");
          console.log('Generated Signature:', signature);

          this.signature = signature;
          this.downloadSignatureFile(this.signature, this.signFile.name);
        } catch (error) {
          console.error('Error generating signature:', error);
        }
      };
      reader.readAsBinaryString(this.signFile);
    },
    calculateHash(data) {
      console.log('Calculating hash...');
      try {
        const hash = CryptoJS.SHA256(data).toString(CryptoJS.enc.Hex);
        console.log('Digest bytes:', hash);
        return hash;
      } catch (error) {
        console.error('Error calculating hash:', error);
        throw error; // Re-throw the error to be caught in the caller
      }
    },
    downloadSignatureFile(data, originalFileName) {
      const fileNameParts = originalFileName.split('.');
      const baseName = fileNameParts.slice(0, -1).join('.');
      const extension = fileNameParts[fileNameParts.length - 1];
      let version = 1;
      let newFileName = `${baseName}.${extension}.sig`;

      while (localStorage.getItem(newFileName)) {
        version++;
        newFileName = `${baseName} (${version}).${extension}.sig`;
      }

      localStorage.setItem(newFileName, 'exists');

      const blob = new Blob([data], { type: 'text/plain' });
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = newFileName;
      document.body.appendChild(a);
      a.click();
      a.remove();
      window.URL.revokeObjectURL(url);
    },
    verifySignature() {
      if (!this.verifyFile || !this.signature || !this.publicKey) {
        alert('请选择文件、签名文件并上传公钥文件');
        return;
      }

      const reader = new FileReader();
      reader.onload = (event) => {
        try {
          const fileContent = event.target.result;
          console.log('File content length:', fileContent.length);

          const hash = this.calculateHash(fileContent);
          console.log('Calculated Hash:', hash);

          const jsEncrypt = new JSEncrypt();
          jsEncrypt.setPublicKey(this.publicKey);

          // Verify the signature using the correct method
          const verified = jsEncrypt.verify(hash, this.signature, CryptoJS.SHA256);
          console.log('Verification Result:', verified);

          this.verificationResult = verified ? '签名验证成功' : '签名验证失败';
        } catch (error) {
          this.verificationResult = '签名验证失败: ' + error.message;
        }
      };
      reader.readAsBinaryString(this.verifyFile);
    },
    downloadFile(blob, filename) {
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = filename;
      document.body.appendChild(a);
      a.click();
      a.remove();
      window.URL.revokeObjectURL(url);
    }
  }
};
</script>

<style scoped>
#signature {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

.upload-demo {
  margin-bottom: 20px;
}
</style>



